using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Sirenix.OdinInspector;

public enum TileType
{
    Wall,
    Floor,
    Door,
    Enemy,
    Player,
}

public class Level : SingletonMono<Level>//MonoBehaviour
{
    [BoxGroup("LevelEditor")]
    [LabelText("Row")]
    [HorizontalGroup("LevelEditor/RowCol")]
    [PropertyOrder(1)]
    [Range(1, 300)]
    public int row = 1;
    [BoxGroup("LevelEditor")]
    [LabelText("col")]
    [HorizontalGroup("LevelEditor/RowCol")]
    [PropertyOrder(1)]
    [Range(1, 300)]
    public int col = 1;
    [BoxGroup("LevelEditor")]
    [LabelText("layer")]
    [HorizontalGroup("LevelEditor/RowCol")]
    [PropertyOrder(1)]
    [Range(1, 300)]
    public int layer = 1;

    [BoxGroup("LevelEditor")]
    [LabelText("width")]
    [HorizontalGroup("LevelEditor/Size")]
    [PropertyOrder(1)]
    [Range(1, 300)]
    public int width = 10;
    [BoxGroup("LevelEditor")]
    [LabelText("height")]
    [HorizontalGroup("LevelEditor/Size")]
    [PropertyOrder(1)]
    [Range(1, 300)]
    public int height = 10;
    [BoxGroup("LevelEditor")]
    [LabelText("length")]
    [HorizontalGroup("LevelEditor/Size")]
    [PropertyOrder(1)]
    [Range(1, 300)]
    public int length = 10;

    [OnValueChanged("OnSelectedLayer")]
    public int selectedLayer = 0;
    public bool IsShowAllGrid = false;

    // instance 
    // public static Level Instance;
    // // awake
    // private void Awake()
    // {
    //     Instance = this;
    // }

    void OnSelectedLayer()
    {
        Debug.Log("OnSelectedLayer");
        if(selectedLayer > layer)
        {
            selectedLayer = layer;
        }else if(selectedLayer <= 0)
        {
            selectedLayer = 0;
        }

    }

    public Vector3 WorldToGridCoordinates(Vector3 point) {
        Vector3 gridPoint = new Vector3(
        (int)((point.x - transform.position.x) / width),
        (int)((point.y - transform.position.y) / height),
        (int)((point.z - transform.position.z) / length));
        return gridPoint;
    }

    public Vector3 GridToWorldCoordinates(int col, int row) {
        Vector3 worldPoint = new Vector3(
        transform.position.x + (col * width + width / 2.0f),
        transform.position.y + (row * height + height / 2.0f),
        transform.position.z + (layer * length + length / 2.0f));
        return worldPoint;
    }

    public bool IsInsideGridBounds(Vector3 point) {
        float minX = transform.position.x;
        float maxX = minX + col * width;
        float minY = transform.position.y;
        float maxY = minY + row * height;
        float minZ = transform.position.z;
        float maxZ = minZ + layer * length;
        return (point.x >= minX && point.x <= maxX && point.y >= minY &&
        point.y <= maxY && point.z >= minZ && point.z <= maxZ);
    }

    public bool IsInsideGridBounds(int col, int row , int layer) {
        return (col >= 0 && col < this.col && row >= 0 && row < this.row && layer >= 0 && layer < this.layer);
    }

    // on gizmo draw
    void OnDrawGizmos()
    {
        Gizmos.color = Color.white;
        if(selectedLayer <= 0 && IsShowAllGrid)
        {
            AllGridGizmo(col, row);
            return;
        }
        GridGizmo(col, row,selectedLayer);
    }

    // draw gizmos gird by scene
    void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.green;
        Gizmos.DrawLine(new Vector3(0, 0, 0), new Vector3(0, 0, row * width));
        Gizmos.DrawLine(new Vector3(0, 0, 0), new Vector3(col *  height, 0, 0));
        Gizmos.DrawLine(new Vector3(col * width, 0, 0), new Vector3(col * width, 0, row * height));
        Gizmos.DrawLine(new Vector3(0, 0, row * width), new Vector3(col * width, 0, row * height));
        
    }

    // draw gizmos gird by layer
    private void GridGizmo(int cols, int rows,int layer)
    {
        if(layer > this.layer || layer <= 0)
        {
            return;
        }
        int len = (layer -1) * length;
        Gizmos.color = Color.yellow;
        Gizmos.DrawLine(new Vector3(0, len, 0), new Vector3(0, len, rows * width));
        Gizmos.DrawLine(new Vector3(0, len, 0), new Vector3(cols *  height, len, 0));
        Gizmos.DrawLine(new Vector3(cols * width, len, 0), new Vector3(cols * width, len, rows * height));
        Gizmos.DrawLine(new Vector3(0, len, rows * width), new Vector3(cols * width, len, rows * height));

        Gizmos.color = Color.white;
        for (int i = 1 ; i < cols ; i++) 
        {
            Gizmos.DrawLine(new Vector3(i * width, len, 0), new Vector3(i * width, len,rows * height));
        }
        for (int j = 1 ; j < rows ; j++) 
        {
            Gizmos.DrawLine(new Vector3(0, len, j * height), new Vector3(cols * width, len, j * height));
        }
    }

    private void AllGridGizmo(int cols, int rows) {

        Gizmos.color = Color.gray;
        Gizmos.DrawLine(new Vector3(0, 0, 0), new Vector3(0, layer * length, 0));
        Gizmos.DrawLine(new Vector3(cols * width, 0, 0), new Vector3(cols * width, layer * length, 0));
        Gizmos.DrawLine(new Vector3(0, 0, rows * height), new Vector3(0, layer * length, rows * height));
        Gizmos.DrawLine(new Vector3(cols * width, 0, rows * height), new Vector3(cols * width, layer * length, rows * height));

        Gizmos.color = Color.red;
        var max_length = layer * length;
        var max_width = cols * width;
        var max_height = rows * height;
        Gizmos.DrawLine(new Vector3(0, max_height, 0), new Vector3(0, max_length, max_height));
        Gizmos.DrawLine(new Vector3(0, max_height, 0), new Vector3(max_width, max_length, 0));
        Gizmos.DrawLine(new Vector3(max_width, max_length, 0), new Vector3(max_width, max_length, max_height));
        Gizmos.DrawLine(new Vector3(max_width, max_length, max_height), new Vector3(0, max_length, max_height));

        for (int z = 0; z < layer; z++)
        {
            int layerOffset = z * length;
            Gizmos.color = Color.yellow;
            Gizmos.DrawLine(new Vector3(0, layerOffset, 0), new Vector3(0, layerOffset, row * width));
            Gizmos.DrawLine(new Vector3(0, layerOffset, 0), new Vector3(col *  height, layerOffset, 0));
            Gizmos.DrawLine(new Vector3(col * width, layerOffset, 0), new Vector3(col * width, layerOffset, row * height));
            Gizmos.DrawLine(new Vector3(0, layerOffset, row * width), new Vector3(col * width, layerOffset, row * height));
            Gizmos.color = Color.white;
            for (int i = 1 ; i < cols ; i++) 
            {
                Gizmos.DrawLine(new Vector3(i * width, layerOffset, 0), new Vector3(i * width, layerOffset,rows * height));
            }
            for (int j = 1 ; j < rows ; j++) 
            {
                Gizmos.DrawLine(new Vector3(0, layerOffset, j * height), new Vector3(cols * width, layerOffset, j * height));
            }
        }
    }
}